package school30;

import java.io.InputStream;
import java.util.Vector;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.TextBox;

import javax.microedition.midlet.MIDlet;
import school30.ui.events.KeyEvent;
import school30.ui.forms.Widget;

public class MainMIDlet extends MIDlet implements CommandListener {

    protected String defaultApp3 = "school30.AppChooser";
    protected int closeAppKey = KeyEvent.KEY_POUND;
    /**
     * -1 - crashed
     * 0 - Init in progress
     * 3 - AppChooser displayed
     */
    private int SYSTEM_STATE = 0;
    static MainMIDlet mainMIDlet;
    static MainCanvas mainCanvas;
    School30App curApp = null;
    Vector apps = new Vector();
    Thread appRunnable = null;

    public String getFile(String file) throws Exception {
        InputStream is = this.getClass().getResourceAsStream(file);
        int len = 0;
        byte[] data = new byte[64];
        StringBuffer sb = new StringBuffer();
        while ((len = is.read(data)) != -1) {
            sb.append(new String(data, 0, len));
        }
        is.close();
        return sb.toString();
    }

    int getHeight(School30App app) {
        return mainCanvas.getHeight();
    }

    int getWidth(School30App app) {
        return mainCanvas.getWidth();
    }

    void keyPressed(int keyCode) {
        if (keyCode != closeAppKey) {
            curApp.keyPressed(keyCode);
        } else {
            terminateCurrentApp();
        }
    }

    void keyReleased(int keyCode) {
        if (keyCode != closeAppKey) {
            curApp.keyReleased(keyCode);
        } else {
            terminateCurrentApp();
        }
    }

    public MainMIDlet() {
        mainMIDlet = this;
        mainCanvas = new MainCanvas(Display.getDisplay(this), (int[]) null);
    }
    //  implementation of MIDlet

    /**
     * Start the application.
     */
    protected void startApp() {
        initSystem();
    }

    /**
     * This method is called to notify the MIDlet to enter a paused
     * state.  The MIDlet should use this opportunity to release
     * shared resources.
     */
    protected void pauseApp() {
    }

    /**
     * If the MIDlet was using resources, it should release
     * them in this method.
     */
    protected void destroyApp(boolean bool) {
        for (int i = 0; i != apps.size(); i++) {
            ((School30App) apps.elementAt(i)).terminateApp();
        }
    }

    public void commandAction(Command cmd, Displayable disp) {
        if (SYSTEM_STATE == -1) {
            notifyDestroyed();
        }
    }

    public void initSystem() {
        try {
            Display.getDisplay(this).setCurrent(mainCanvas);
            mainCanvas.startAnimation();
            startDefault();
            SYSTEM_STATE = 3;
        } catch (Exception ex) {
            ex.printStackTrace();
            showSystemCrashMessage("System init failed. ", ex);
        }
    }

    public void startDefault()
            throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        startSchool30App(defaultApp3);
    }

    public void showSystemCrashMessage(String info) {
        SYSTEM_STATE = -1;
        TextBox t = new TextBox("System crash",
                info, 512, 0);
        t.addCommand(new Command("Exit", Command.EXIT, 0));
        t.setCommandListener(this);
        Display.getDisplay(this).setCurrent(t);
    }

    public void showSystemCrashMessage(Exception ex) {
        showSystemCrashMessage(ex.getClass().getName() + ": " + ex.getMessage());
    }

    public void showSystemCrashMessage(String s, Exception ex) {
        showSystemCrashMessage(s + " " + ex.getClass().getName() + ": " + ex.getMessage());
    }

    public void startSchool30App(String className)
            throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        curApp = (School30App) Class.forName(className).newInstance();
        apps.addElement(curApp);
        appRunnable = new Thread(
                new Runnable() {

                    public void run() {
                        curApp.startApp();
                    }
                });
        appRunnable.start();
    }

    public void terminateCurrentApp() {
        curApp.terminateApp();
        apps.removeElement(curApp);
        if (!apps.isEmpty()) {
            curApp = (School30App) apps.elementAt(apps.size() - 1);
        } else {
            try {
                startDefault();
            } catch (Exception ex) {
                showSystemCrashMessage(ex);
            }
        }
    }

    void refresh() {
        if (mainCanvas != null) {
            mainCanvas.repaint();
        }
    }
}
